iT邦幫忙

2021 iThome 鐵人賽

DAY 16
0
自我挑戰組

ASP.NET Core & Blazor系列 第 17

Day 17 建立Blog跟Post

  • 分享至 

  • xImage
  •  

接下來就是跟資料庫連結了,會著重說明 ASP.NET Core 跟 EF Core,如果有需要改畫面才會說到 Blazor,這邊會花比較多篇幅著墨。

Blog

首先要把 Blog 跟 Post 分開,我們先在NavMenu.razor加入指向 Blog 的連結,接著將Blog.razor改寫,因為BlogId必須有值且大於0才是一筆部落格資料,所以我們在BlogId等於0時顯示一個表單讓使用者輸入部落格名稱,另外在BlogModelBlogName加上Required attribute,畢竟一個部落格要有名字。
https://ithelp.ithome.com.tw/upload/images/20210916/20140893jt7a1ek76B.png
https://ithelp.ithome.com.tw/upload/images/20210916/20140893DdCuf2ULCh.png
https://ithelp.ithome.com.tw/upload/images/20210916/20140893pnE9OPjjb9.png
https://ithelp.ithome.com.tw/upload/images/20210916/20140893R6XmxnQaY3.png

不等於0的話則顯示部落格名稱及底下的日誌,且部落格名稱改用<h3>元素。
https://ithelp.ithome.com.tw/upload/images/20210916/20140893BSaJbVYfTv.png

12行有個參數OnValidSubmit="createBlog",代表的是如果表單驗證通過,則執行指定的 function createBlog,筆者先寫好一個放在那裡,等說完取資料的部分會再說明。
(註:如果希望觸發OnValidSubmit,必須有個type="submit"的按鈕,否則不管怎麼按都沒效果)

有人問那如果BlogId小於0呢?因為這個欄位是資料庫由1開始遞增產生,通常不會有這問題,除非有人竄改資料庫,真的擔心的話可以在資料庫加入不可小於0的機制。

畫面有了,接著來取資料,我們在根目錄建立一個資料夾 Repository,建立一個介面 interface IBlogRepository,Repository 裡面再建立一個資料夾 Implement,建立一個類別 class BlogRepository,資料夾結構因人而異,筆者是因為看到同事這樣用,覺得可以快速找到介面跟實作很方便。
https://ithelp.ithome.com.tw/upload/images/20210916/20140893Q7sBFSeWQg.png

介面做的事情很簡單,就是規範方法;實作的 13 到 18 行是依賴注入AppDbContext;19 到 27行是取得第一筆 Blog,21行的 Include() 就是昨天說的不用自己 join table的方法,全名為Eager loading,只要建表的時候有建好關聯,就可以節省時間,其他還有Explicit loadingLazy loading,都是 Entity Framework Core 提供的方便作法,如果是一對一的關聯在 SQL 語法會被翻譯成 Inner Join,一對多則是 Left Join
https://ithelp.ithome.com.tw/upload/images/20210916/20140893CffIPEwj5b.pnghttps://ithelp.ithome.com.tw/upload/images/20210916/20140893fdePaXzHVC.png

正常來說 Blog 會跟登入者 (User) 綁定,可能有張 Table 記錄BlogIdUserId,但目前還沒實作登入機制,所以就取第一筆資料,如果沒有第一筆代表還沒建立,回傳空的 Blog;28 到 43行則是建立 Blog 的方法,30 到 31 行先檢查 Blog 是否存在,不存在則建立 Blog,而不論是否存在,都回傳型別為ResultViewModel的物件,裡面只有兩個 Property:IsSuccessMessage,前端收到後是否要根據IsSuccess做事,就是前端的事了。
https://ithelp.ithome.com.tw/upload/images/20210916/20140893vQF5tsNIoo.png

接著去Startup.cs註冊剛才寫的 Repository,有些人可能會問,上面的GuidService跟之前建立的PostService為什麼叫 Service 這邊卻叫 Repository,這是筆者的習慣,筆者此前開發的 Blazor 專案是多層式架構,分別為後端 API、中介 Model、前端 Blazor,後端處理資料的檔案都以 Repository做為後綴詞,前端取得資料的檔案則以 Service 做為後綴詞,端看不同公司的開發模式。後來筆者將 Service 抽成另一個專案,再後來又將 DbContext 抽成一個專案,都是為了方便日後有其他專案要參考 Model 或是只是要調動 Service 的話,不需要參考整個 Blazor 或是 API 專案。
https://ithelp.ithome.com.tw/upload/images/20210916/20140893JZlmpgNOf0.png

最後就是BlogBase.razor.cs了,16 到 17 行注入IBlogRepositoryIJSRuntime,23 到 27 行改成非同步方法,因為取資料、存資料都用非同步,所以這邊也要跟進;28到 31 行就是呼叫剛才寫的GetBlog()方法取得 Blog;32 到 43 行是這篇一開始說到的createBlog()方法,這裡如果成功的話就取得 Blog 資料,失敗則用前面說過的JsInteropClasses顯示後端來的Message
https://ithelp.ithome.com.tw/upload/images/20210916/20140893Ipw2YdYxAC.png

接著讓我們輸入部落格名稱,輸入送出後,可以看到畫面不同了,去看資料庫,Blog 也能看到一筆資料。
https://ithelp.ithome.com.tw/upload/images/20210916/20140893JBuGAJrNWK.pnghttps://ithelp.ithome.com.tw/upload/images/20210916/20140893dVW5aFp18S.png

Post

前面說完 Blog,今天來說 Post 的部分,先建立IPostRepositoryPostRepository,裡面只有CreatePost()DeletePost()兩個方法,那怎麼沒有取得單篇的GetPost()或是多篇的GetPosts()方法呢?因為 Blog 的GetBlog()已經帶入 Posts 所以不需要GetPosts(),如果之後有需要看到個別日誌的話,再建立GetPost()
(註:筆者參與的系統不多,也不知道這樣的系統規劃是否常見,只是因為一開始沒有完整規劃才會這樣做。)
https://ithelp.ithome.com.tw/upload/images/20210918/20140893aXb75JCo4V.png

CreatePost()如果在資料庫找不到 Post 就新增一筆,找得到就修改,既然要修改就要有修改時間,所以我們在PostModel.cs加上UpdateDateTime欄位,用指令Add-Migration新增一個 Migration 後下指令Update-Database更新資料庫,然後去Startup.cs註冊這個新建的 Repository。
(註:前面說過的內容筆者就不附圖了,避免占版面。)
https://ithelp.ithome.com.tw/upload/images/20210918/201408938hr9AiRXxN.png
https://ithelp.ithome.com.tw/upload/images/20210918/20140893TkkfiKJJyk.png

再來去PostBase.razor.cs注入PostRepository,改寫一下deletePost(),新增一個按下Submit按鈕會觸發的事件createPost()PostBase.razor加上前面加入的更新時間UpdateDateTimeOnValidSubmit="createPost"Submit按鈕的type改成submit,讓表格真的有送出功能。
https://ithelp.ithome.com.tw/upload/images/20210918/201408936CT6sJQqhE.pnghttps://ithelp.ithome.com.tw/upload/images/20210918/20140893qM53nFliAF.png

接下來就是重頭戲了,我們回到BlogBase.razor.cs,把postId刪除,因為用不到了,add()則改成傳BlogIdCreateDateTime到新的PostModel,讓這筆日誌知道是跟著哪個 Blog。
https://ithelp.ithome.com.tw/upload/images/20210918/201408936wq9VREGo7.png

產生CreateDateTimeUpdateDateTime有兩種選擇:在前端或後端決定,端看系統如何規劃,因為這邊在 add 一筆 Post 的當下要避免看到0001-01-01 12:00:00這樣的尷尬時間,所以我們在前端給DateTime.Now,至於後端要不要覆蓋掉前端來的時間,就是規劃問題了。
https://ithelp.ithome.com.tw/upload/images/20210918/20140893sUk3jR9ATg.png

接著把PostModel.Content[MinLength]改成50,因為不想打太多字XD。

打完內容後點擊 Submit 按鈕,我們的第一篇日誌就建立成功了!
https://ithelp.ithome.com.tw/upload/images/20210918/20140893ps5RYGSkbq.png

實際去看資料庫,可以看到有資料,跟 BlogId 的關聯也正確。
https://ithelp.ithome.com.tw/upload/images/20210918/20140893krfeRRxLEj.png

不過時間好像怪怪的,明明是晚上卻顯示早上時間,我們把Post.razor@bind:format的小時格式改成大寫H,畫面的時間就正常了。
https://ithelp.ithome.com.tw/upload/images/20210918/20140893uwaLoBVDat.png

(註:因為這邊的操作是以前學的,也忘記在哪裡看的,就附上學習來源)
Ref: Blazor tutorial for beginners

Ref: Loading Related Data


上一篇
Day 16 建立資料庫
下一篇
Day 18 修改add()方法
系列文
ASP.NET Core & Blazor30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言